package library

///
// 运行信息库
///
import (
	"fmt"
	"reflect"
	"runtime"
	"strconv"
	"strings"
)

// MemorySize 内存占用
func MemorySize() uint64 {
	runtime.GC() //GC，排除对象影响
	var memStat runtime.MemStats
	runtime.ReadMemStats(&memStat)
	return memStat.Sys
}

// CallMyName 调用来源
func CallMyName(value int) string {
	pc, _, _, _ := runtime.Caller(value + 2)
	return runtime.FuncForPC(pc).Name()
}

// GetFunc 获取函数信息
func GetFunc(value interface{}) *runtime.Func {
	return runtime.FuncForPC(reflect.ValueOf(value).Pointer())
}

// CallTrace 获得调用栈信息
func CallTrace(value int) (S string) {
	pc := make([]uintptr, 10) // at least 1 entry needed
	n := runtime.Callers(value+2, pc)
	frames := runtime.CallersFrames(pc[:n])
	for {
		frame, more := frames.Next()
		S += fmt.Sprintf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
		if !more {
			break
		}
	}
	return
}

// GetGid 获得 GoroutineID
func GetGid() (int, error) {
	var buf [64]byte
	n := runtime.Stack(buf[:], false)
	idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
	id, err := strconv.Atoi(idField)
	if err != nil {
		return 0, err
	}
	return id, nil
}

// GoGexit 退出协程
func GoGexit() {
	runtime.Goexit()
}
